<template>
  <div class="flex-col-center letter-practice">
    <div class="flex-row-center">
      <t-w-info-box @refresh="handleClickRestart" :info="twInfo" class="info-box" ></t-w-info-box>
      <div class="clickable flex-row-between">
<!--        播放声音-->
        <el-icon v-show="globalSetting.playAudio" @click="handleClickPlayAudioSetting"><Bell /></el-icon>
        <el-icon v-show="!globalSetting.playAudio" @click="handleClickPlayAudioSetting"><MuteNotification /></el-icon>

      </div>
      <div class="margin-row-10 flex-row-center">
        <div style="font-size: 12px;color: grey">总计</div>
        <el-input-number class="margin-row-5"
                         :disabled="config.showResult"
                         size="small"
                         v-model="config.inputNum"
                         :min="1"
                         :max="100"
                         @change="handleChangeTotal" />
      </div>
    </div>

    <div class="flex-col-center letter-board" >
<!--      字母-->
      <div :class="['letter', 'flex-col-center',computedStatus]" v-show="!config.showResult">
        {{ computedLetter }}
      </div>

      <!--      最终结果-->
      <ResultDialog @sure="handleClickRestart" :list="letterList" v-model="config.showResult"></ResultDialog>
<!--      <Result class="margin-col-10" :list="letterList" v-if="config.showResult" style="width: 70%"></Result>-->
<!--      <el-button @click="handleClickRestart" v-show="config.showResult" type="primary">重新开始</el-button>-->
    </div>

    <div class="notice" v-show="!config.showResult">按下相应字母按键</div>
    <TotalInfoBox :total="config.total" :curr="currIndex"></TotalInfoBox>
    <div class="bottom-progress">
      <y-progress
                  color="var(--theme-color)"
                  :percent="currIndex/config.total*100"
                  v-show="globalSetting.showProgress"
      >

      </y-progress>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, reactive, ref, watch} from "vue";
import TWInfoBox from "@/components/infobox/TWInfoBox.vue";
import Result from "@/components/result/Result.vue";
import {RecordItem, RecordStatus} from "@/ts/record";
import useKeyboard from "@/hooks/useKeyboard";

import { KeyboardEventMode} from "@/ts/keyboard";
import {Bell,  MuteNotification} from "@element-plus/icons";
import {ElMessage,ElMessageBox} from "element-plus";
import TotalInfoBox from "@/components/infobox/TotalInfoBox.vue";
import YProgress from "@/components/progress/YProgress.vue";
import GlobalSettingStore from "@/store/globalSettingStore";
import {TWInfo} from "@/ts/record";
import userTimer from "@/hooks/useTimer"
import ResultDialog from "@/components/result/ResultDialog.vue";
let timer=userTimer()

enum StatusType{
  VOID,
  SUCCESS,
  ERROR
}

// 引入settingStore
let {globalSetting} = GlobalSettingStore()
// 临时状态,判断当前字母正确与否，0未用/1正确/2错误
let status = ref(0)
// 配置
let config=reactive({
  // 字母切换间隔
  duration:1000,
  showResult:false,
  volume:100,
  total:10,
  inputNum:10
})
let twInfo=ref<TWInfo>({
  currNum: 0,
  errorNum: 0,
  rightNum: 0,
  time: 0,
  total: 0
})
// 字母表
let letterList = ref<RecordItem[]>([])
// 当前字母表索引
let currIndex = ref(0)



// 键盘事件hook
let {start} = useKeyboard()
// 音频
let errorAudio = new Audio(require("@/assets/audio/answerError.mp3"))
let rightAudio = new Audio(require("@/assets/audio/answerRight.mp3"))

// 启动键盘监听
start({
  duration: config.duration,
  mode: KeyboardEventMode.SIMPLE,
  exclude:['1','2','3', '4','5','6','7','8','9'],
  callback:callback
})

let init=()=>{


  // 初始化字母索引
  currIndex.value=0

  // 初始化字母表
  letterList.value.splice(0,letterList.value.length)
  letterList.value.push(...randomLetterList(config.total))

  // 显示字母
  config.showResult=false

  // 初始化字母状态
  status.value=0

  twInfo.value={

    currNum: 0,
    errorNum: 0,
    rightNum: 0,
    total: 0

  }
  timer.stopTime()
  timer.startTime()
}
init()

function success(){

  status.value=StatusType.SUCCESS
  twInfo.value.rightNum++

}
function error(){
  twInfo.value.errorNum++
  status.value=StatusType.ERROR

}

function end(){
  timer.stopTime()
  config.showResult=true
}

// 键盘输入回调方法：用于处理按键
function callback(index:number,name:string){
  // 完成后，不再判断
  if( currIndex.value >= letterList.value.length ){
    // 显示结果
    config.showResult=true
    return
  }
  // 判断正误
    let curr=letterList.value[currIndex.value]
    // 修改临时字母状态
  if(name.toLowerCase() === curr.value.toLowerCase()){
    success()
  }else{
    error()
  }
  // 修改当前记录项正确/错误
  curr.status=status.value
    // 播放音效
    if(globalSetting.playAudio){
      status.value===1?playRightAudio():playErrorAudio()
    }
    // 还原临时状态，下一个字母
  // 索引++
  setTimeout(()=>{
    // 归零状态
    status.value=0
    currIndex.value++
  },config.duration)
}

function randomLetterList(total:number) {
  let lst:Array<RecordItem> = [];
  for (let i = 0; i < total; i++) {
    let letter = String.fromCharCode(Math.random() * 25 + 65)
    lst.push({
      status: RecordStatus.VOID,
      value: letter
    })
  }
  return lst
}

let playErrorAudio = () => {
  errorAudio.play()
}

let playRightAudio = () => {
  rightAudio.play()
}
let computedStatus=computed(()=>{
  switch (status.value){
    case 0:return ''
    case 1:return 'success'
    case 2:return 'error'
  }
  return ''
})

let handleClickRestart=()=>{
  ElMessage({
    type:"success",
    message:"刷新成功"
  })
  init()
}
let handleClickPlayAudioSetting=()=>{
  let curr= globalSetting.playAudio
  globalSetting.playAudio=!curr
  let text = curr?'关闭':'开启'
  ElMessage({
    message: text+'声音',
    showClose: true,
    duration:800,
    type: 'success',
  })
}
let handleChangeTotal=()=>{
  // 正常
  if( currIndex.value+1 <= config.inputNum){
    // 更新total
    config.total = config.inputNum
    // 求差值
    let diff = config.total - letterList.value.length
    if( diff > 0 ){
      // 增加了,直接加尾
      letterList.value.push(...randomLetterList(diff))
    }else {
      // 减少了去除
      letterList.value.splice(letterList.value.length+diff-1,-diff)
    }
  }else{// 逆反
    ElMessageBox.confirm("确定修改吗?(会丢失当前进度)",{
      title:"提示",
      confirmButtonText:"确定",
      cancelButtonText:"取消"
    }).then(()=>{
      // 重新初始化
      config.total=config.inputNum
      init()
    }).catch(()=>{
      // 还原值
      config.inputNum = config.total
    })

  }

}
let computedLetter=computed(()=>{
  // 防止越界
  let index=currIndex.value < letterList.value.length?currIndex.value:letterList.value.length-1
  return letterList.value[index].value
})

// 修改时间
watch(timer.time,(newV)=>{
  twInfo.value.time=newV
})
// 修改总长
watch(letterList,(newV)=>{
  twInfo.value.total=newV.length
},{deep:true})
watch(currIndex,(newV)=>{

  twInfo.value.currNum=newV

  // 打字结束显示结果
  if( currIndex.value === letterList.value.length ){
    end()
  }
})
</script>

<style scoped lang="less">
.letter-practice {
  width: 100%;
  .info-box{

  }
  .letter {
    font-size: 170px;
    color: grey;
    transition: all 0.3s;
    caret-color: transparent;

  }

  .small-letter {
    font-size: 30px;
    caret-color: transparent;
    width: 2em;
    height: 2em;
    border-radius: 0.1em;
    margin: 0.1em;

  }

  .score {
    font-size: 60px;
    color: gold;
    font-weight: 660;
  }

  .process {
    position: absolute;
    right: 10em;
    top: 10em;

    span:first-child {
      font-size: 35px;
      color: tomato;
      margin-right: 5px;
    }

    span:last-child {
      font-size: 60px;
      color: black;
    }
  }

  .letter-board {
    min-height: 70vh;
    .error {
      animation: swing-row 0.3s ease-in-out 0s 3 alternate;
    }
  }
  .notice{
    position: absolute;
    bottom: 3em;
    color: grey;
  }
  .bottom-progress{
    width: 100%;
    height: 6px;
    position: fixed;
    bottom: 0;
    left: 0;
  }
  .success {
    color: #407D54;
  }

  .error {
    color: #9E2E22;

  }

}

</style>